package com.example.zdxk.util;

import javax.xml.bind.DatatypeConverter;
import java.util.regex.Pattern;

public class FormatUtil {

    /*
    计算CheckSum
     */
    public static int checksum(String datas) {
        byte[] data=hexStringToBytes(datas);
        int len=data.length;


        int sum = 0;
        for (int j=0; len > 1; len--) {
            sum += data[j++]&0xff;
            if ((sum & 0x80000000)>0) {
                sum = (sum & 0xffff) + (sum >> 16);//使用1的补码
            }
        }
        if (len == 1) {
            sum += data[data.length-1]&0xff;
        }
        while ((sum >> 16)>0) {
            sum = (sum & 0xffff) + sum >> 16;
        }
        sum=(sum == 0xffff) ? sum& 0xffff : (~sum)&0xffff;
        return sum;
    }

    /**
     *      校验码，字节数组异或
     * @param data
     * @return
     */
    public static byte getXor(byte[] data) {
        byte temp = data[0];
        for (int i = 1; i < data.length; i++) {
            temp ^= data[i];
        }
        return temp;
    }
        public static int checksum(byte[] data, int len) {
        int sum = 0;
        for (int j=0; len > 1; len--) {
            sum += data[j++]&0xff;
            if ((sum & 0x80000000)>0) {
                sum = (sum & 0xffff) + (sum >> 16);//使用1的补码
            }
        }
        if (len == 1) {
            sum += data[data.length-1]&0xff;
        }
        while ((sum >> 16)>0) {
            sum = (sum & 0xffff) + sum >> 16;
        }
        sum=(sum == 0xffff) ? sum& 0xffff : (~sum)&0xffff;
        return sum;
    }

    /*
     * (非16进制)字符转换为字节
     */
    private static byte charToByte(char c) {
        return (byte) "0123456789ABCDEF".indexOf(c);
    }

    /**
     * 将字节转换为十六进制字符串
     * 顾名思义，char* 是一个指针类型。0x0f是一个地址。
     * 而0x是16位形式的数字, 0x0f 转换到二进制，就是 00001111。
     * 0x表示的是 16进制, 0f 表示 15
     * @param mByte
     * @return
     */
    public static String byteToHexStr(byte mByte) {
        char[] Digit = { '0', '1', '2', '3', '4', '5', '6', '7', '8', '9', 'A', 'B', 'C', 'D', 'E', 'F' };
        char[] tempArr = new char[2];
        tempArr[0] = Digit[(mByte >>> 4) & 0X0F];
        tempArr[1] = Digit[mByte & 0X0F];

        String s = new String(tempArr);
        return s;
    }

    /*
     * 16进制字符串转byte数组
     */
    public static byte[] hexStringToBytes(String hex) {

        if ((hex == null) || (hex.equals(""))) {
            return null;
        } else if (hex.length() % 2 != 0) {         //不是偶数位
            hex = "0"+hex;
            hex = hex.toUpperCase();
            int len = hex.length() / 2;
            byte[] b = new byte[len];
            char[] hc = hex.toCharArray();
            for (int i = 0; i < len; i++) {
                int p = 2 * i;
                b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1]));
            }
            //byte[] c = new byte[b.length-1];
            //System.arraycopy(b, 1, c, 0, b.length-1);
            return b;
        } else {
            hex = hex.toUpperCase();
            int len = hex.length() / 2;
            byte[] b = new byte[len];
            char[] hc = hex.toCharArray();
            for (int i = 0; i < len; i++) {
                int p = 2 * i;
                b[i] = (byte) (charToByte(hc[p]) << 4 | charToByte(hc[p + 1]));
            }
            return b;
        }
    }

    /*
     * int转byte[4]
     */
    public static byte[] intToBytes4(int num) {
        byte[] result = new byte[4];
        result[0] = (byte) ((num >>> 24) & 0xff);// 说明一
        result[1] = (byte) ((num >>> 16) & 0xff);
        result[2] = (byte) ((num >>> 8) & 0xff);
        result[3] = (byte) ((num >>> 0) & 0xff);
        return result;
    }

    /*
     * int转byte[2]
     */
    public static byte[] intToBytes2(int num) {
        byte[] result = new byte[2];
        result[0] = (byte) ((num >>> 8) & 0xff);
        result[1] = (byte) ((num >>> 0) & 0xff);
        return result;
    }
    public static byte intToBytes(int num) {
        byte result ;
        result = (byte) ((num >>> 0) & 0xff);
        return result;
    }
    /*
     * byte[4]转int
     */
    public static int bytes4ToInt(byte[] bytes) {
        int result = 0;
        if (bytes.length == 4) {
            int a = (bytes[0] & 0xff) << 24;// 说明二
            int b = (bytes[1] & 0xff) << 16;
            int c = (bytes[2] & 0xff) << 8;
            int d = (bytes[3] & 0xff);
            result = a | b | c | d;
        }
        return result;
    }

    /*
     * byte[2]转int
     */
    public static int bytes2ToInt(byte[] bytes) {
        int result = 0;
        if (bytes.length == 2) {
            int c = (bytes[0] & 0xff) << 8;
            int d = (bytes[1] & 0xff);
            result = c | d;
        }

        return result;
    }
    public static int bytes1ToInt(byte[] bytes) {
        int result = 0;
        if (bytes.length == 1) {

            int d = (bytes[0] & 0xff);
            result = d;
        }

        return result;
    }





    /*
     * BCD码转为10进制串(阿拉伯数字)
     */
    public static String bcdToStr(byte[] bytes){
        StringBuffer temp=new StringBuffer(bytes.length*2);

        for(int i=0;i<bytes.length;i++){
            temp.append((byte)((bytes[i]& 0xf0)>>>4));
            temp.append((byte)(bytes[i]& 0x0f));
        }
        return temp.toString().substring(0,1).equalsIgnoreCase("0")?temp.toString().substring(1):temp.toString();
    }

    /*
     * 10进制串转为BCD码
     */
    public static byte[] strToBcd(String asc) {
        int len = asc.length();
        int mod = len % 2;

        if (mod != 0) {
            asc = "0" + asc;
            len = asc.length();
        }

        byte abt[] = new byte[len];
        if (len >= 2) {
            len = len / 2;
        }

        byte bbt[] = new byte[len];
        abt = asc.getBytes();
        int j, k;

        for (int p = 0; p < asc.length()/2; p++) {
            if ( (abt[2 * p] >= '0') && (abt[2 * p] <= '9')) {
                j = abt[2 * p] - '0';
            } else if ( (abt[2 * p] >= 'a') && (abt[2 * p] <= 'z')) {
                j = abt[2 * p] - 'a' + 0x0a;
            } else {
                j = abt[2 * p] - 'A' + 0x0a;
            }

            if ( (abt[2 * p + 1] >= '0') && (abt[2 * p + 1] <= '9')) {
                k = abt[2 * p + 1] - '0';
            } else if ( (abt[2 * p + 1] >= 'a') && (abt[2 * p + 1] <= 'z')) {
                k = abt[2 * p + 1] - 'a' + 0x0a;
            }else {
                k = abt[2 * p + 1] - 'A' + 0x0a;
            }

            int a = (j << 4) + k;
            byte b = (byte) a;
            bbt[p] = b;
        }
        return bbt;
    }


    /**
     *   判断是否是数字
     */
    public static boolean isInteger(String str) {
        Pattern pattern = Pattern.compile("^[-\\+]?[\\d]*$");
        return pattern.matcher(str).matches();
    }

    /**
     *      CC 01 00  ->   00 01 CC      每两位字符反转
     */
    public static String reverse(byte[] s){
        String data_str = DatatypeConverter.printHexBinary(s);
        char[] data = data_str.toCharArray();
        for(int i=0,j=data.length-2; i<data.length/2; i=i+2,j=j-2){
            char tmp1 = data[i];
            char tmp2 = data[i+1];
            data[i] = data[j];
            data[i+1] = data[j+1];
            data[j] = tmp1;
            data[j+1] = tmp2;
        }

        return new String(data);
    }


    // 从byte数组的index处的连续8个字节获得一个long
    public static long getLong(byte[] arr, int index) {
        return 	(0xff00000000000000L 	& ((long)arr[index+0] << 56))  |
                (0x00ff000000000000L 	& ((long)arr[index+1] << 48))  |
                (0x0000ff0000000000L 	& ((long)arr[index+2] << 40))  |
                (0x000000ff00000000L 	& ((long)arr[index+3] << 32))  |
                (0x00000000ff000000L 	& ((long)arr[index+4] << 24))  |
                (0x0000000000ff0000L 	& ((long)arr[index+5] << 16))  |
                (0x000000000000ff00L 	& ((long)arr[index+6] << 8))   |
                (0x00000000000000ffL 	&  (long)arr[index+7]);
    }
    // double转换为byte[8]数组
    public static byte[] getByteArray(double d) {
        long longbits = Double.doubleToLongBits(d);
        return getByteArray(longbits);
    }
    // 从byte数组的index处的连续8个字节获得一个double
    public static double getDouble(byte[] arr, int index) {
        return Double.longBitsToDouble(getLong(arr, index));
    }


}
